package com.qf.weekexam.service.impl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.text.csv.CsvReader;
import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qf.weekexam.dao.UserDao;
import com.qf.weekexam.entity.User;
import com.qf.weekexam.ex.UserException;
import com.qf.weekexam.service.UserService;
import com.qf.weekexam.utils.Constants;
import com.qf.weekexam.vo.HelperPageVo;
import com.qf.weekexam.vo.ResultVo;
import com.qf.weekexam.vo.TableVo;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService {

    /**
     * 用户头像上传路径
     */
    @Value("${qfsy.Profilephotopath}")
    private String Profilephotopath;

    /**
     * 全量导出文件存储位置
     */
    @Value("${qfsy.exportFilePath}")
    private String exportFilePath;

    /**
     * 文件浏览器附件下载的位置
     */
    @Value("${qfsy.fileDownloadPath}")
    private String fileDownloadPath;

    /**
     * 文件上传
     */
    @Value("${qfsy.uploadfile}")
    private String uploadfile;

    @Value("${qfsy.fileuploadimage}")
    private String fileuploadimage;


    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    UserDao userDao;

    /**
     * 登录验证
     * @param username
     * @param password
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public User login(String username, String password) {

        User user = userDao.getOneUserByName(username);
        if (user == null){  // 没用匹配的用户，直接返回null
            return null;
        }else {
            //2. 比对密码是否正确
            final String dbpassword = user.getPassword();

            // 转换 password 为 md5 字符串
            final String md5password = DigestUtil.md5Hex(password);

            if (dbpassword.equals(md5password)){
                return user;
            }

            return null;
        }
    }

    /**
     * 查询数据显示到面板中
     * @param helperPageVo
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public TableVo<User> getUserByHelper(HelperPageVo helperPageVo) {

        // 声明要查询第几页的数据，以及每页的数据条数
        PageHelper.startPage(helperPageVo.getPage(),helperPageVo.getLimit());
        //查询数据
        List<User> allUser = userDao.getAllUserByLimit(helperPageVo);
        //获取数据总条数
        PageInfo<User> userPageInfo = new PageInfo<>(allUser);
        int count = (int) userPageInfo.getTotal();
        TableVo vo = TableVo.ok(count, allUser);
        return vo;

    }

    /**
     * 添加用户
     * @param user
     * @throws UserException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addUser(User user) throws UserException {
        //1.判断用户名是否存在
        String uname = user.getName();
        User dbauser = userDao.getOneUserByName(uname);
        if(dbauser!=null){
            throw new UserException("-1001","验证码错误");
        }
        //2.密码处理
        String md5Password = DigestUtil.md5Hex(user.getPassword());

        user.setPassword(md5Password);

        //3.加用户
        userDao.insertUser(user);
    }


    /**
     * 全量导出
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String export() {
        //1.定义文件导出位置

        String fileName = "user.csv";

        String filePath = exportFilePath + fileName;

        List<User> allUsers = userDao.getAllUsers();

        //把books追加到文本文件
        FileUtil.writeLines(allUsers,filePath,"utf-8",false);

        String[] split = filePath.split("/");

        String userName = split[2];

        return userName;

    }

    @Override
    public void downFile(String filename, HttpServletResponse response) throws IOException {
        //文件的完整路径
        String real_path = fileDownloadPath+filename;

        //设置响应头  告知浏览器，要以附件的形式保存内容   filename=浏览器显示的下载文件名
        response.setHeader("content-disposition","attachment;filename="+filename);

        //读取目标文件，写出给客户端
        IOUtils.copy(new FileInputStream(real_path), response.getOutputStream());
    }

    /**
     * 删除选中用户
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delUsers(Integer[] ids) {
        userDao.delUserById(ids);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateUserById(User user) throws UserException {
        //1.判断user中是否存在id
        Integer id = user.getId();
        if(id==null){
            throw new UserException("-1020","修改用户没有id");
        }
        //1.5判断密码是否被更改了
        String password = user.getPassword();
        User dbuser = userDao.getUserById(id);
        String dbpassword = dbuser.getPassword();
        if(!dbpassword.equals(password)){
            String md5password = DigestUtil.md5Hex(password);
            if(md5password.equals(dbpassword)){
                throw new UserException("-1003","两次密码不一样");
            }else {
                user.setPassword(md5password);
            }
        }

        //2.更新用户数据
        userDao.updateUserById(user);
    }

    /**
     * 全量导入
     * @param multipartFile
     * @return
     */
    @Override
    public ResultVo uploadFile(MultipartFile multipartFile) throws IOException {


        //1.获取文件名

        String originalFilename = multipartFile.getOriginalFilename();

        //2.存储文件路径

        String uploadpath = uploadfile + originalFilename;

        //3.上传文件到指定路径

        multipartFile.transferTo(new File(uploadpath));


        //4. 读取csv文件中的内容，转换为 List<User>

        final CsvReader reader = CsvUtil.getReader();
        //4.1假设csv文件在classpath目录下
        final List<User> userList = reader.read(
                ResourceUtil.getUtf8Reader(uploadpath), User.class);

        //4.2 批量插入user数据
        userDao.insertUserList(userList);

        return ResultVo.okupload(uploadpath);
    }

    public ResultVo getUserPhoto(HttpSession session) {
        User user = (User) session.getAttribute(Constants.USER_SESSION_KEY);
        if(user!=null){
            String finalPath = fileuploadimage + user.getPhotopath();
            ResultVo vo =  ResultVo.portrait(finalPath,user.getName());
            return vo;
        }
        return ResultVo.error("当前用户不存在");
    }

    @Override
    public void getUserImage(HttpSession session, HttpServletResponse response) throws IOException {
        User user = (User) session.getAttribute(Constants.USER_SESSION_KEY);
        //文件的完整路径
        String real_path = fileuploadimage + user.getPhotopath();

        //读取目标文件，写出给客户端
        IOUtils.copy(new FileInputStream(real_path), response.getOutputStream());
    }
}
